package com.maibow.util.baidu;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;

import net.sf.json.JSONObject;

import com.maibow.entity.baidu.AddressComponent;
import com.maibow.entity.baidu.BaiduLocation;
import com.maibow.entity.baidu.BaiduLocationAddress;
import com.maibow.entity.baidu.Location;
import com.maibow.util.Logger;

public class BaiduUtil {
    protected Logger logger = Logger.getLogger(this.getClass());

    /**
     * 获得位置经纬度
     * getBaiduLocation(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param ak
     * 标记：@param address
     * 标记：@return
     * 返回值：BaiduLocation
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    public BaiduLocation getBaiduLocation(String ak, String address) {
        BaiduLocation baiduLocation = null;
        String requestUrl = BaiduConstants.GET_BAIDULOCATION_URL.replace("ADDRESS", address).replace("AK", ak);
        String json = httpRequest(requestUrl, "GET", null);
        json = json.replaceAll("showLocation&&showLocation\\(", "");
        json = json.substring(0, json.length() - 1);
        JSONObject jsonObject = JSONObject.fromObject(json);
        // 如果请求成功
        if (null != jsonObject) {
            try {
                baiduLocation = new BaiduLocation();
                if (jsonObject.getInt("status") == 0) {
                    JSONObject result = jsonObject.getJSONObject("result");
                    baiduLocation.setPrecise(result.getInt("precise"));
                    baiduLocation.setConfidence(result.getInt("confidence"));
                    baiduLocation.setLevel(result.getString("level"));
                    Location location = new Location();
                    location.setLat(result.getJSONObject("location").getDouble("lat"));
                    location.setLng(result.getJSONObject("location").getDouble("lng"));
                    baiduLocation.setLocation(location);
                } else {
                    baiduLocation = null;
                }
            } catch (Exception e) {
                baiduLocation = null;
                // 获取token失败
                logger.debug("获取位置失败 errcode:{} errmsg:{}");
            }
        }
        return baiduLocation;
    }

    /**
     */
    public BaiduLocationAddress getBaiduLocationAddress(String ak, String location) {
        BaiduLocationAddress baiduLocationAddress = null;
        String requestUrl = BaiduConstants.GET_BAIDULOCATION_ADDRESS_URL.replace("LOCATION", location).replace("AK", ak);
        String json = httpRequest(requestUrl, "GET", null);
        json = json.replaceAll("renderReverse&&renderReverse\\(", "");
        json = json.substring(0, json.length() - 1);
        JSONObject jsonObject = JSONObject.fromObject(json);
        // 如果请求成功
        if (null != jsonObject) {
            try {
                baiduLocationAddress = new BaiduLocationAddress();
                if (jsonObject.getInt("status") == 0) {
                    JSONObject result = jsonObject.getJSONObject("result");
                    baiduLocationAddress.setBusiness(result.getString("business"));
                    AddressComponent addressComponent = new AddressComponent();
                    addressComponent.setCity(result.getJSONObject("addressComponent").getString("city"));
                    addressComponent.setProvince(result.getJSONObject("addressComponent").getString("province"));
                    addressComponent.setStreet(result.getJSONObject("addressComponent").getString("street"));
                    addressComponent.setStreet_number(result.getJSONObject("addressComponent").getString("street_number"));
                    baiduLocationAddress.setAddressComponent(addressComponent);
                } else {
                    baiduLocationAddress = null;
                }
            } catch (Exception e) {
                baiduLocationAddress = null;
                // 获取token失败
                logger.debug("获取位置详细地址失败 errcode:{} errmsg:{}");
            }
        }
        return baiduLocationAddress;
    }

    private String httpRequest(String requestUrl, String requestMethod, String outputStr) {
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            return buffer.toString();
        } catch (ConnectException ce) {
            logger.debug("Baidu server connection timed out.");
        } catch (Exception e) {
            logger.debug("error.");
        }
        return null;
    }

    public static void main(String[] args) {
        BaiduUtil util = new BaiduUtil();
        String address = "麓谷信息港";
        BaiduLocation location = util.getBaiduLocation(BaiduConstants.AK, address);
        System.out.println(location.getLocation().getLat() + " " + location.getLocation().getLng());
        String locationStr = location.getLocation().getLat() + "," + location.getLocation().getLng();
        BaiduLocationAddress baiduLocationAddress = util.getBaiduLocationAddress(BaiduConstants.AK, locationStr);
        System.out.println(baiduLocationAddress.getBusiness() + " " + baiduLocationAddress.getAddressComponent().getProvince() + baiduLocationAddress.getAddressComponent().getCity()
                            + baiduLocationAddress.getAddressComponent().getStreet());
    }
}
